﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConferenceArranger.ConferenceComponent;

namespace ConferenceArranger.BusinessRules
{
    /// <summary>
    /// contains configurations and rules for session-related tasks
    /// </summary>
    static class SessionHelper
    {
        //use the dummy date to create DateTime object since only time is used
        public static DateTime DEFAULT_DATE = new DateTime(1, 1, 1);

        //max number of sessions for each track
        public static int MAX_NUM_OF_SESSIONS = 2;

        public static int LUNCH_TIME = 12;
        public static int EARLY_NETWORKING_TIME = 16;
        public static int LATE_NETWORKING_TIME = 17;
        public static int MORNING_START_HOUR = 9;
        public static int AFTERNOON_START_HOUR = 13;
        public static int MORNING_INTERVAL = 180;
        public static int AFTERNOON_INTERVAL = 240;

        /// <summary>
        /// returns default date
        /// currently only time is used
        /// </summary>
        /// <returns></returns>
        public static DateTime GetNextStartDate()
        {
            return DEFAULT_DATE;
        }

        /// <summary>
        /// AM for Moring, PM for Afternoon
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string GetSessionTimeCode(string type)
        {
            switch (type)
            {
                case "Morning":
                    return "AM";
                default:
                    return "PM";
            }

        }

        /// <summary>
        /// return the correct period for each type of session
        /// Morning: 180 mins, Afternoon: 240 mins
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static int GetSessionInterval(string type)
        {
            switch (type)
            {
                case "Morning":
                    return MORNING_INTERVAL;
                default:
                    return AFTERNOON_INTERVAL;
            }
        }

        /// <summary>
        /// return the correct start time for each type of session
        /// Morning session starts at 9AM
        /// Afternoon session starts at 1PM
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static int GetSessionStartHour(string type)
        {
            switch (type)
            {
                case "Morning":
                    return MORNING_START_HOUR;
                default:
                    return AFTERNOON_START_HOUR;
            }
        }

        /// <summary>
        /// after setting time for each talk of a session
        /// this class helps to set the correct time for break(lunch or networking)
        /// </summary>
        /// <param name="lastEventEndtime"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Break SetBreak(DateTime lastEventEndtime, string type)
        {
            Break sessionBreak = new Break();
            switch (type)
            {
                case "Morning":
                    DateTime lunchTime =
                        new DateTime(lastEventEndtime.Year, lastEventEndtime.Month, lastEventEndtime.Day, LUNCH_TIME, 0, 0);
                    sessionBreak.SetStartTime(lunchTime);
                    sessionBreak.SetActivity("Lunch");
                    break;

                default:
                    DateTime networkingTime;
                    DateTime earlieastTime = new DateTime(lastEventEndtime.Year, lastEventEndtime.Month, lastEventEndtime.Day, EARLY_NETWORKING_TIME, 0, 0);
                    DateTime latestTime = new DateTime(lastEventEndtime.Year, lastEventEndtime.Month,
                                              lastEventEndtime.Day, LATE_NETWORKING_TIME, 0, 0);

                    if (lastEventEndtime.CompareTo(earlieastTime) <= 0)
                        networkingTime = earlieastTime;
                    else if (lastEventEndtime.CompareTo(latestTime) > 0)
                        networkingTime = new DateTime(1, 1, 1);
                    else networkingTime = lastEventEndtime;
                    sessionBreak.SetStartTime(networkingTime);
                    sessionBreak.SetActivity("Networking Event");
                    break;
            }
            return sessionBreak;
        }


        /// <summary>
        /// return the default Session Type
        /// </summary>
        /// <returns></returns>
        public static string GetNextSessionType()
        {
            return "Morning";
        }

        /// <summary>
        /// inform current track about the next session type
        /// Morning and Afternoon will be used interchangeably
        /// </summary>
        /// <param name="currentSessionType"></param>
        /// <returns></returns>
        public static string GetNextSessionType(string currentSessionType)
        {
            if (currentSessionType.Equals("Morning"))
                return "Afternoon";
            else return "Morning";
        }

        /// <summary>
        /// Given the list of talks for each session, help to set time for each talk
        /// Timing also depends on whether the session is morning or afernoon
        /// </summary>
        /// <param name="talkList">Talk list for the session</param>
        /// <param name="sessionType"></param>
        /// <param name="startDate">start date of session's track</param>
        /// <returns></returns>
        public static List<Talk> SetStartTimeForEvent(List<Talk> talkList, string sessionType, DateTime startDate)
        {
            int sessionStartHour = GetSessionStartHour(sessionType);
            DateTime sessionStartDateTime = startDate.AddHours(sessionStartHour);
            DateTime talkStartTime = sessionStartDateTime;
            for (int i = 0; i < talkList.Count; i++)
            {
                talkList[i].SetStartTime(talkStartTime);
                talkStartTime = talkStartTime.AddMinutes(talkList[i].GetInterval());
            }

            return talkList;
        }

        /// <summary>
        /// help to convert time format of talks or breaks according to the requirements
        /// </summary>
        /// <param name="eventTime"></param>
        /// <returns></returns>
        public static string ConvertTimeFormat(DateTime eventTime)
        {
            string timeString = eventTime.ToShortTimeString();
            timeString = timeString.Replace(" ", "");
            string hour = timeString.Substring(0, timeString.IndexOf(":"));
            if (hour.Length == 1) timeString = "0" + timeString;
            return timeString;
        }
    }
}

